package com.atguigu.netty.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;


/**
 * 我们自定义的一个handler，需要继承netty规定好的某个HandlerAdapter（规范）
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    //读取数据事件（这里可以读取客户端发送的消息）
    /*
        1.ChannelHandlerContext ctx：上下文对象，包含管道pipeline,通道channel
        2.Object msg: 就是客户端发送的数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //比如这里有一个非常耗时的业务，异步执行提交该channel
        //NIOEventLoop的taskQueue中

        //解决方案1：用户程序自定义的普通任务
        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10*1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端2",CharsetUtil.UTF_8));
            }
        });

        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10*1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端3",CharsetUtil.UTF_8));
            }
        });
        //用户自定义定时任务-》 该任务提交到scheduleTaskQueue
        ctx.channel().eventLoop().schedule(new Runnable(){
            @Override
            public void run() {
                try {
                    Thread.sleep(10*1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端4",CharsetUtil.UTF_8));
            }
        },5, TimeUnit.SECONDS);

        System.out.println("go  on");
//        System.out.println("服务器读取线程 "+Thread.currentThread().getName());
//        System.out.println("server ctx=" + ctx);
//        System.out.println("看看channel和pipeline的关系");
//        Channel channel = ctx.channel();
//        ChannelPipeline pipeline = ctx.pipeline();//本质是一个双向链表
//
//
//        //将msg转成ByteBuffer
//        //ByteBuf netty提供的
//        ByteBuf buf = (ByteBuf) msg;
//        System.out.println("客户端发送消息是："+buf.toString(CharsetUtil.UTF_8));
//        System.out.println("客户端地址："+ctx.channel().remoteAddress());
    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //writeAndFlush 是write + flush
        //将数据写入缓存并刷新
        //我们对这个数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello, 客户端",CharsetUtil.UTF_8));
    }

    //处理异常,一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
